package com.ruoyi.basedata.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.ruoyi.basedata.domain.GoodsType;
import com.ruoyi.basedata.mapper.GoodsMapper;
import com.ruoyi.basedata.mapper.GoodsTypeMapper;
import com.ruoyi.basedata.service.IGoodsService;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.basedata.Goods;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.utils.PageUtils.startPage;

/**
 * 商品Service业务层处理
 *
 * @author wl
 * @date 2024-10-25
 */
@Service
@Slf4j
public class GoodsServiceImpl implements IGoodsService {
    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GoodsTypeMapper goodsTypeMapper;

    /**
     * 查询商品
     *
     * @param id 商品主键
     * @return 商品
     */
    @Override
    public Goods selectGoodsById(Integer id) {
        Goods goods = goodsMapper.selectGoodsById(id);
        log.info("GoodsServiceImpl selectGoodsById id:{} goods:{}", id, goods);
        return goods;
    }

    /**
     * 查询商品列表
     *
     * @param goods 商品
     * @return 商品
     */
    @Override
    public List<Goods> selectGoodsList(Goods goods) {
        List<GoodsType> goodsTypeList = new ArrayList<>();
        if (goods.getTypeId() != null) {
            GoodsType goodsType = goodsTypeMapper.selectGoodsTypeById(goods.getTypeId());
            goodsTypeList.add(goodsType);
            List<GoodsType> goodsTypeChilrenList = new ArrayList<>();
            for (GoodsType type : goodsTypeList) {
                goodsTypeChilrenList.addAll(getGoodsTypeChilrenList(type.getId()));
            }
            goodsTypeList.addAll(goodsTypeChilrenList);

            List<Integer> ids = new ArrayList<>();
            ids.add(goodsType.getId());
            for (GoodsType type : goodsTypeList) {
                ids.add(type.getId());
            }
            goods.setTypeIds(ids);
        }

        startPage();
        List<Goods> goodsList = goodsMapper.selectGoodsList(goods);
        log.info("GoodsServiceImpl selectGoodsList goodsList:{}", goodsList);
        return goodsList;
    }

    /**
     * @return com.ruoyi.common.core.web.domain.AjaxResult
     * @description 获取所有商品
     * @date 2024/10/26 下午11:55
     **/
    public AjaxResult listAll() {
        List<Goods> goodsList = goodsMapper.selectGoodsList(null);
        log.info("GoodsServiceImpl listAll goodsList:{}", goodsList);
        return AjaxResult.success(goodsList);
    }

    @Override
    public List<Goods> selectGoodsListByIds(List<Integer> ids) {
//         goodsMapper.selectGoodsListByIds(Arrays.asList(ids));
        return goodsMapper.selectGoodsListByIds(ids);
    }


    /**
     * @return com.ruoyi.common.core.web.domain.AjaxResult
     * @description 根据商品id获取成本
     * @date 2024/11/8 上午10:03
     * @Param goodsId:
     **/
    public R<BigDecimal> getCostByGoodsId(Integer id) {
        BigDecimal cost = goodsMapper.selectCostByGoodsId(id);
        return R.ok(cost);
    }

    /**
     * 新增商品
     *
     * @param goods 商品
     * @return 结果
     */
    @Override
    public AjaxResult insertGoods(Goods goods) {
        if (StringUtils.isBlank(goods.getProCode())) {
            return AjaxResult.error("商品编码不能为空");
        }
        int checkNum = goodsMapper.selectGoodsCountByProCode(goods.getProCode());
        if (checkNum > 0) {
            return AjaxResult.error("商品编码已存在");
        }
        if (StringUtils.isBlank(goods.getProName())) {
            return AjaxResult.error("商品名称不能为空");
        }
        if (goods.getPrice() != null && goods.getPrice().compareTo(BigDecimal.ZERO) < 0) {
            return AjaxResult.error("商品价格不能为负数");
        }
        if (goods.getTypeId() == null) {
            return AjaxResult.error("商品类型不能为空");
        }
        //根据当前用户设置创建人
        goods.setCost(BigDecimal.ZERO);
        goods.setCreateBy(SecurityUtils.getUsername());
        goods.setCreateDate(new Date());
        goods.setIsDel(0);
        int addNum = goodsMapper.insertGoods(goods);
        log.info("GoodsServiceImpl insertGoods goods:{} addNum:{}", goods, addNum);
        if (addNum > 0) {
            return AjaxResult.success();
        }
        return AjaxResult.error("新增商品失败");
    }

    /**
     * 修改商品
     *
     * @param goods 商品
     * @return 结果
     */
    @Override
    public AjaxResult updateGoods(Goods goods) {
        if (goods.getId() == null) {
            return AjaxResult.error("商品id不能为空");
        }
        if (goods.getPrice() != null && goods.getPrice().compareTo(BigDecimal.ZERO) < 0) {
            return AjaxResult.error("商品价格不能为负数");
        }
        //根据当前登录用户修改
        goods.setModifyBy(SecurityUtils.getUsername());
        goods.setModifyDate(new Date());
        int updNum = goodsMapper.updateGoods(goods);
        log.info("WarehouseGoodsServiceImpl updateGoods updNum: {}", updNum);
        if (updNum > 0) {
            return AjaxResult.success();
        }
        return AjaxResult.error("500", "修改失败");
    }

    /**
     * 批量删除商品
     *
     * @param ids 需要删除的商品主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteGoodsByIds(Integer[] ids) {
        if (ids == null) {
            return AjaxResult.error("商品id不能为空");
        }
        int delNum = goodsMapper.deleteGoodsByIds(ids);
        log.info("GoodsServiceImpl deleteGoodsByIds ids:{} delNum:{}", ids, delNum);
        if (delNum > 0) {
            return AjaxResult.success();
        }
        return AjaxResult.error("删除失败");
    }

    /**
     * 删除商品信息
     *
     * @param id 商品主键
     * @return 结果
     */
    @Override
    public AjaxResult deleteGoodsById(Integer id) {
        if (id == null) {
            return AjaxResult.error("商品id不能为空");
        }
        int delNum = goodsMapper.deleteGoodsById(id);
        log.info("GoodsServiceImpl deleteGoodsById id:{} delNum:{}", id, delNum);
        if (delNum > 0) {
            return AjaxResult.success();
        }
        return AjaxResult.error("删除失败");
    }

    /**
     * @return com.ruoyi.common.core.web.domain.AjaxResult
     * @description 校验商品编码是否重复
     * @date 2024/10/25 上午1:41
     * @Param proCode:
     **/
    public AjaxResult checkProCode(String proCode) {
        int checkNum = goodsMapper.selectGoodsCountByProCode(proCode);
        log.info("GoodsServiceImpl checkProCode proCode:{} checkNum:{}", proCode, checkNum);
        if (checkNum > 0) {
            return AjaxResult.error("商品编码已存在");
        }
        return AjaxResult.success();
    }

    /**
     * @return java.util.List<com.finer.entity.document.FinerGoodsType>
     * @description 从数据库中获取子分类
     * @date 2024/10/23 上午10:25
     * @Param parentId:
     **/
    public List<GoodsType> getGoodsTypeChilrenList(Integer parentId) {
        List<GoodsType> res = new ArrayList<>();
        List<GoodsType> childrenList = new ArrayList<>();
        GoodsType goodsType = new GoodsType();
        goodsType.setParentId(parentId);
        childrenList = goodsTypeMapper.selectGoodsTypeList(goodsType);
        if (childrenList != null && !childrenList.isEmpty()) {
            res.addAll(childrenList);
            for (GoodsType type : childrenList) {
                res.addAll(getGoodsTypeChilrenList(type.getId()));
            }
        }
        return res;
    }


    /**
     * @return java.util.List<com.finer.entity.document.FinerGoodsType>
     * @description 递归获取子分类
     * @date 2024/10/23 上午10:26
     * @Param parentId:
     * @Param goodsTypeList:
     **/
    public List<GoodsType> getChildrenList(Integer parentId, List<GoodsType> goodsTypeList) {
        List<GoodsType> childrenList = goodsTypeList
                .stream()
                .filter(goodsType -> {
                    return Objects.equals(goodsType.getParentId(), parentId);
                })
                .map(goodsType -> {
                    goodsType.setChildren(getChildrenList(goodsType.getId(), goodsTypeList));
                    return goodsType;
                })
                .collect(Collectors.toList());
        log.info("childrenList: {}", childrenList);
        return childrenList;
    }

}
